package com.lqq.chapter03.sync;

/**
 * @Author lqq677
 * @Date 2021/8/9 22:04
 * @Description 线程通信，演示虚假唤醒
 */

//资源类
class Noodles {
    //面的数量
    private int num = 0;

    //厨师做面的方法
    public synchronized void incr() throws InterruptedException {
        //判断，如果面的数量为1，则等待食客吃完面再做面
        //if (num == 1) { 虚假唤醒问题
        while (num == 1) {
            //等待
            this.wait();
        }
        //干活 +1
        num++;
        System.out.println(Thread.currentThread().getName()+"做好了一份面，当前有"+num+"份面");
        //通知顾客吃面
        this.notifyAll();
    }

    //顾客吃面的方法
    public synchronized void decr() throws InterruptedException {
        //判断，如果面的数量为0，则等待厨师做完面再吃面
        //if (num == 0) { 虚假唤醒问题
        while (num == 0) {
            //等待
            this.wait();
        }
        //干活 顾客吃面
        num--;
        System.out.println(Thread.currentThread().getName()+"吃了一份面，当前有"+num+"份面");
        //通知厨师做面
        this.notifyAll();
    }

}


public class ThreadDemo {
    public static void main(String[] args) {

        Noodles noodles = new Noodles();

        //+1线程 厨师A做面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
                }, "厨师A").start();

        //-1线程 顾客甲吃面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "顾客甲").start();

        //+1线程 厨师B做面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "厨师B").start();

        //-1线程 顾客乙吃面
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    noodles.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "顾客乙").start();
    }
}
